/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.com.claro.administracionSolicitudes.beans;

import co.com.claro.administracionSolicitudes.dao.exceptions.ClaroException;
import co.com.claro.administracionSolicitudes.db.EJBDatabaseSolicitudesLocal;
import co.com.claro.administracionSolicitudes.ejb.EJBAdminSolicitudesLocal;
import co.com.claro.administracionSolicitudes.entity.Aplicacion;
import co.com.claro.administracionSolicitudes.entity.EstadosSolicitud;
import co.com.claro.administracionSolicitudes.entity.Gerencia;
import co.com.claro.administracionSolicitudes.entity.Perfil;
import co.com.claro.administracionSolicitudes.entity.PrivilegioSolicitud;
import co.com.claro.administracionSolicitudes.entity.Solicitud;
import co.com.claro.administracionSolicitudes.entity.TipoAplicacion;
import co.com.claro.administracionSolicitudes.entity.TipoUsuario;
import co.com.claro.administracionSolicitudes.entity.Usuario;
import co.com.claro.administracionSolicitudes.entity.UsuariosPorAplicaciones;
import co.com.claro.administracionSolicitudes.entity.enums.AccionesEnum;
import co.com.claro.administracionSolicitudes.entity.enums.EstadoActividadEnum;
import co.com.claro.administracionSolicitudes.entity.enums.EstadosSolicitudEnum;
import co.com.claro.administracionSolicitudes.entity.enums.TipoSolicitudEnum;
import co.com.claro.administracionSolicitudes.entity.enums.TipoUsuarioEnum;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Set;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;

/**
 *
 * @author Mike
 */
@ManagedBean
@ViewScoped
public class SolicitudBean {

    @EJB
    private EJBDatabaseSolicitudesLocal localDatabase;
    @EJB
    private EJBAdminSolicitudesLocal localAdminSol;
    @ManagedProperty(value = "#{usuarioSessionBean}")
    private UsuarioSessionBean sesionBean;

    private final static int ID_ADMIN_SOL = 1;

    /**
     * Variable que almacena el usuario que está logeado en el sistema
     */
    private Usuario usuarioLogeado;
    /**
     * Lista de los tipos de usuarios para mostrar en la interfaz de usuario
     */
    private List<SelectItem> tipoUsuarioItems;
    /**
     * Lista de las aplicaciones a las que puede acceder un usuario de una
     * gerencia
     */
    private List<SelectItem> aplicacionItems;
    /**
     * Lista con los perfiles a los que tiene acceso esa aplicación
     */
    private List<SelectItem> perfilItems;
    /**
     * Lista con los tipos de solicitud disponibles
     */
    private List<SelectItem> tiposSolicitudItems;
    /**
     * Objeto seleccionado del select one menu tab aplicaciones
     */
    private String tipoUsuarioSeleccionado;
    /**
     * Objeto seleccionado del select one menu tab elementos
     */
    private String tipoUsuarioElementosSeleccionado;
    /**
     * Objeto seleccionado del select one menu tab requerimientos
     */
    private String tipoUsuarioRequerimientosSeleccionado;
    /**
     * Aplicación seleccionada por el usuario
     */
    private String aplicacionSeleccionado;
    /**
     * Perfil seleccionado por el usuario
     */
    private String perfilSeleccionado;
    /**
     * Variable que almacena la ip de origen del firewall
     */
    private String ipOrigenFirewall;
    /**
     * Variable que almacena la ip de destino del firewall
     */
    private String ipDestinoFirewall;
    /**
     * Variable que almacena la fecha del inicio de la vigencia del usuario
     * temporal
     */
    private Date fechaInicioVigencia;
    /**
     * Variable que almacena la fecha del fin de la vigencia del usuario
     * temporal
     */
    private Date fechaFinVigencia;
    /**
     * Variable usada para almacenar los comentarios del usuario
     */
    private String comentariosUsuario;
    /**
     * Variable usada para almacenar la acción seleccionada por el usuario
     */
    private String accionSeleccionada;
    private List<SelectItem> accionesItems;
    /**
     * Variable encargada de mostrar o coultar las fechas de vigencia para un
     * tipo empleado temporal
     */
    private boolean mostrarVigencia;
    /**
     * Variable que contiene el mensaje de error o confirmación de la acción
     * realizada por el usuario
     */
    private String mensaje;

    /**
     * Creates a new instance of SolicitudBean
     */
    public SolicitudBean() {
    }

    @PostConstruct
    public void inicializarValores() {
        usuarioLogeado = sesionBean.getUsuario();
        llenarTipoUsuarios();
        llenarAplicaciones();
        llenarTipoSolicitudes();
    }

    //++++++++++++++++++++++++++++++ MÉTODOS PROPIOS DEL BEAN ++++++++++++++++++++
    /**
     * Método que llena las solicitudes a mostrar en pantalla
     */
    private void llenarTipoUsuarios() {
        List<TipoUsuario> tipoUsuarios;
        tipoUsuarios = localDatabase.findTipoUsuarios();

        if (tipoUsuarioItems == null) {
            tipoUsuarioItems = new ArrayList<SelectItem>();
        }
        for (TipoUsuario temporal : tipoUsuarios) {
            tipoUsuarioItems.add(new SelectItem(temporal.getIdTipoUsuario(), temporal.getNombre()));
        }
    }

    /**
     * Método que llena los tipos de solicitud a mostrar en pantalla
     */
    private void llenarTipoSolicitudes() {
        List<TipoAplicacion> tipoAplicaciones = localDatabase.findTipoAplicacionByEstado(EstadoActividadEnum.ACTIVO.getId());

        if (tiposSolicitudItems == null) {
            tiposSolicitudItems = new ArrayList<SelectItem>();
        }
        for (TipoAplicacion temporal : tipoAplicaciones) {
            tiposSolicitudItems.add(new SelectItem(temporal.getIdTipoAplicacion(), temporal.getNombre()));
        }
    }

    /**
     * Método que llena las aplicaciones dependiendo de la gerencia a la que
     * pertenezca
     */
    private void llenarAplicaciones() {
        Gerencia gerencia = usuarioLogeado.getGerencia();
        Set<Aplicacion> aplicaciones = new HashSet<Aplicacion>();

        List<PrivilegioSolicitud> privilegios = localDatabase.findPrivilegioByGerencia(gerencia.getIdGerencia());

        if (aplicacionItems == null) {
            aplicacionItems = new ArrayList<>();
        }

        for (PrivilegioSolicitud temporal : privilegios) {
            aplicaciones.add(temporal.getIdAplicacion());
        }

        for (Aplicacion temporal : aplicaciones) {
            aplicacionItems.add(new SelectItem(temporal.getIdAplicacion(), temporal.getNombre()));
        }
    }

    public void llenarAcciones() {
        accionesItems = new ArrayList<SelectItem>();

        if (aplicacionSeleccionado != null) {
            if (Integer.parseInt(aplicacionSeleccionado) != ID_ADMIN_SOL) {
                accionesItems.add(new SelectItem(AccionesEnum.CREACION.getId(), AccionesEnum.CREACION.getNombre()));
                accionesItems.add(new SelectItem(AccionesEnum.ELIMINACION.getId(), AccionesEnum.ELIMINACION.getNombre()));
                accionesItems.add(new SelectItem(AccionesEnum.CAMBIO_PASSWORD.getId(), AccionesEnum.CAMBIO_PASSWORD.getNombre()));
                accionesItems.add(new SelectItem(AccionesEnum.CAMBIO_PERFIL.getId(), AccionesEnum.CAMBIO_PERFIL.getNombre()));
            } else {
                accionesItems.add(new SelectItem(AccionesEnum.ELIMINACION.getId(), AccionesEnum.ELIMINACION.getNombre()));
            }
        }
    }

    /**
     * Método que llena los perfiles dependiendo de la aplicación que escoja
     */
    public void llenarPerfiles() {
        perfilItems = new ArrayList<SelectItem>();

        if (aplicacionSeleccionado != null) {
            List<PrivilegioSolicitud> p = localDatabase.findPrivilegioByAplicacionGerencia(Integer.parseInt(aplicacionSeleccionado),
                    sesionBean.getUsuario().getGerencia().getIdGerencia());

            for (PrivilegioSolicitud privilegioSolicitud : p) {
                perfilItems.add(new SelectItem(
                        privilegioSolicitud.getIdPerfil().getIdPerfil(),
                        privilegioSolicitud.getIdPerfil().getNombre()));
            }
        }
    }

    /**
     * Método que evalua si los campos del formulario estan bien o indica
     * mensaje de error
     *
     * @return boolean, true si todos los campos están llenos, false si falta
     * algún campo
     */
    private boolean isCamposInvalidos() {
        if (tipoUsuarioSeleccionado == null) {
            String error = ResourceBundle.getBundle("errores").getString("errorAplicacionSeleccionada");
            incluirMensaje(error);
            return true;
        }
        if (perfilSeleccionado == null) {
            String error = ResourceBundle.getBundle("errores").getString("errorPerfilSeleccionado");
            incluirMensaje(error);
            return true;
        }
        if (accionSeleccionada == null) {
            String error = ResourceBundle.getBundle("errores").getString("errorAccionSeleccionada");
            incluirMensaje(error);
            return true;
        }
        if (mostrarVigencia) {
            if ((fechaFinVigencia == null) && (fechaInicioVigencia == null)) {
                String error = ResourceBundle.getBundle("errores").getString("errorFechasVigenciaUsuario");
                incluirMensaje(error);
                return true;
            }
            if (fechaFinVigencia != null && (fechaInicioVigencia == null)) {
                String error = ResourceBundle.getBundle("errores").getString("errorFechasVigenciaUsuario");
                incluirMensaje(error);
                return true;
            }
            if ((fechaFinVigencia == null) && fechaInicioVigencia != null) {
                String error = ResourceBundle.getBundle("errores").getString("errorFechasVigenciaUsuario");
                incluirMensaje(error);
                return true;
            }
        }

        return false;
    }

    /**
     * Método que toma un mensaje enviado y lo pasa al contexto para que sea
     * mostrado en la interfaz gráfica del usuario
     *
     * @param String, mensaje con el error que se desea mostrar.
     */
    private void incluirMensaje(String error) {
//        FacesContext.getCurrentInstance().addMessage(null, 
//            new FacesMessage(FacesMessage.SEVERITY_INFO, error, null));
        mensaje = error;
    }

    /**
     * Método que obtiene el rótulo de un item a partir del objeto seleccionado
     *
     * @param items, la lista de items en la que se va a buscar
     * @param seleccionado, el item que seleccionó el usuario
     * @return String, con el rótulo que tiene ese item.
     */
    private String obtenerStringItem(List<SelectItem> items, Integer seleccionado) {
        for (SelectItem selectItem : items) {
            if (selectItem.getValue().equals(seleccionado)) {
                return selectItem.getLabel();
            }
        }
        return null;
    }

    /**
     * Método que obtiene el nombre de la acción a partir de su id
     *
     * @param accionSeleccionada, id de la acción seleccionada por el usuario
     * @return String, nombre de la acción seleccionada
     */
    private AccionesEnum obtenerAccion(short accionSeleccionada) {
        for (AccionesEnum acciones : AccionesEnum.values()) {
            if (acciones.getId() == accionSeleccionada) {
                return acciones;
            }
        }
        return null;
    }

    /**
     * Método que borra los campos cuando se han hecho modificaciones
     */
    private void borrarCampos() {
        tipoUsuarioSeleccionado = null;
        aplicacionSeleccionado = null;
        perfilSeleccionado = null;
        fechaInicioVigencia = null;
        fechaFinVigencia = null;
        comentariosUsuario = null;
        accionSeleccionada = null;
    }

    //******************************************** EVENTOS DEL BEAN ***************************************//
    /**
     * Método que identifica si los calendario de vigencia se muestran o se
     * ocultan dependiendo del tipo de usuario que escoja el usuario
     */
    public void tipoUsuarioSeleccionado() {
        short tipoUsuario = Short.parseShort(tipoUsuarioSeleccionado);

        if (tipoUsuario == TipoUsuarioEnum.TEMPORAL.getId()) {
            mostrarVigencia = true;
        }

        if (tipoUsuario == TipoUsuarioEnum.FIJO.getId()) {
            mostrarVigencia = false;
        }
    }

    /**
     * Método que crea la solicitud y la envía para que se cree en la Base de
     * Datos
     *
     * @param event, evento de quien lanzó la acción
     */
    public void enviarSolicitudAplicaciones(ActionEvent event) {
        if (isCamposInvalidos()) {
            borrarCampos();
            return;
        }

        short tipoAplicacion = TipoSolicitudEnum.APLICACION.getId();;
        UsuariosPorAplicaciones usrxapps = new UsuariosPorAplicaciones();
        Calendar calendario = Calendar.getInstance();
        Aplicacion aplicacion = new Aplicacion(Integer.parseInt(aplicacionSeleccionado));
        Perfil perfil = new Perfil(Integer.parseInt(perfilSeleccionado));
        StringBuilder nombreUsuario = new StringBuilder(usuarioLogeado.getNombres());
        EstadosSolicitud estadoSolicitud = new EstadosSolicitud(EstadosSolicitudEnum.POR_APROBAR.getId());

        //Se obtienen los recursos para ingresarlos en las entidades
        Solicitud solicitud = new Solicitud();
        nombreUsuario.append(" ");
        nombreUsuario.append(usuarioLogeado.getApellidos());
        String descripcion = ResourceBundle.getBundle("mensajes").getString("solicitudAplicacion");
        String aplicacionStr = obtenerStringItem(aplicacionItems, Integer.parseInt(aplicacionSeleccionado));
        String perfilStr = obtenerStringItem(perfilItems, Integer.parseInt(perfilSeleccionado));
        AccionesEnum accion = obtenerAccion(Short.parseShort(accionSeleccionada));

        //Se llena la entidad usuario x aplicaciones, que es la aplicación, el perfil y el tipo de usuario
        //que se quiere crear
        usrxapps.setActivo(EstadoActividadEnum.INACTIVO.getId());
        usrxapps.setInicioVigencia(fechaInicioVigencia);
        usrxapps.setFinVigencia(fechaFinVigencia);
        usrxapps.setIdAplicacion(aplicacion);
        usrxapps.setIdTipoUsuario(new TipoUsuario(Short.parseShort(tipoUsuarioSeleccionado)));
        usrxapps.setIdUsuario(usuarioLogeado);

        //se crea la descripción de la solicitud
        descripcion = MessageFormat.format(descripcion, nombreUsuario.toString(), accion.getNombre(), aplicacionStr, perfilStr);

        //Se llena la entidad solicitud
        solicitud.setActivo(EstadoActividadEnum.ACTIVO.getId());
        solicitud.setDescripcion(descripcion);
        solicitud.setEstado(estadoSolicitud);
        solicitud.setFechaSolicitud(new Date(calendario.getTimeInMillis()));
        solicitud.setIdSolicitante(usuarioLogeado);
        solicitud.setGerenciaAprobadora(usuarioLogeado.getGerencia());
        solicitud.setGerenciaAsignadora(localDatabase.findAplicacion(aplicacion.getIdAplicacion()).getGerenciaAsignadora());
        solicitud.setAplicacion(aplicacion);
        solicitud.setUsuario(usuarioLogeado.getUsername());
        solicitud.setAccion(Short.parseShort(accionSeleccionada));
        solicitud.setPerfil(perfil);
        solicitud.setUsuarioApp(usrxapps);

        try {
            localAdminSol.enviarSolicitudAplicacion(solicitud, usrxapps, accion, tipoAplicacion);
            incluirMensaje(ResourceBundle.getBundle("mensajes").getString("solicitudCreadoOk"));
            borrarCampos();
        } catch (ClaroException ex) {
            incluirMensaje(ex.getMessage());
            borrarCampos();
        }
    }

    /**
     * Método que crea la solicitud y la envía para que se cree en la Base de
     * Datos
     *
     * @param event, evento de quien lanzó la acción
     */
    public void enviarSolicitudElementos(ActionEvent event) {

    }

    /**
     * Método que crea la solicitud y la envía para que se cree en la Base de
     * Datos
     *
     * @param event, evento de quien lanzó la acción
     */
    public void enviarSolicitudRequerimientos(ActionEvent event) {

    }

    /**
     * Método que crea la solicitud y la envía para que se cree en la Base de
     * Datos
     *
     * @param event, evento de quien lanzó la acción
     */
    public void enviarSolicitudFirewall(ActionEvent event) {

    }

    //******************************************** GETTERS Y SETTERS ***************************************//
    public List<SelectItem> getTipoUsuarioItems() {
        return tipoUsuarioItems;
    }

    public void setTipoUsuarioItems(List<SelectItem> tipoUsuarioItems) {
        this.tipoUsuarioItems = tipoUsuarioItems;
    }

    public String getTipoUsuarioSeleccionado() {
        return tipoUsuarioSeleccionado;
    }

    public void setTipoUsuarioSeleccionado(String tipoUsuarioSeleccionado) {
        this.tipoUsuarioSeleccionado = tipoUsuarioSeleccionado;
    }

    public List<SelectItem> getAplicacionItems() {
        return aplicacionItems;
    }

    public void setAplicacionItems(List<SelectItem> aplicacionItems) {
        this.aplicacionItems = aplicacionItems;
    }

    public String getAplicacionSeleccionado() {
        return aplicacionSeleccionado;
    }

    public void setAplicacionSeleccionado(String aplicacionSeleccionado) {
        this.aplicacionSeleccionado = aplicacionSeleccionado;
    }

    public List<SelectItem> getPerfilItems() {
        return perfilItems;
    }

    public void setPerfilItems(List<SelectItem> perfilItems) {
        this.perfilItems = perfilItems;
    }

    public String getPerfilSeleccionado() {
        return perfilSeleccionado;
    }

    public void setPerfilSeleccionado(String perfilSeleccionado) {
        this.perfilSeleccionado = perfilSeleccionado;
    }

    public UsuarioSessionBean getSesionBean() {
        return sesionBean;
    }

    public void setSesionBean(UsuarioSessionBean sesionBean) {
        this.sesionBean = sesionBean;
    }

    public boolean isMostrarVigencia() {
        return mostrarVigencia;
    }

    public void setMostrarVigencia(boolean mostrarVigencia) {
        this.mostrarVigencia = mostrarVigencia;
    }

    public Date getFechaInicioVigencia() {
        return fechaInicioVigencia;
    }

    public void setFechaInicioVigencia(Date fechaInicioVigencia) {
        this.fechaInicioVigencia = fechaInicioVigencia;
    }

    public Date getFechaFinVigencia() {
        return fechaFinVigencia;
    }

    public void setFechaFinVigencia(Date fechaFinVigencia) {
        this.fechaFinVigencia = fechaFinVigencia;
    }

    public String getComentariosUsuario() {
        return comentariosUsuario;
    }

    public void setComentariosUsuario(String comentariosUsuario) {
        this.comentariosUsuario = comentariosUsuario;
    }

    public String getAccionSeleccionada() {
        return accionSeleccionada;
    }

    public void setAccionSeleccionada(String accionSeleccionada) {
        if (accionSeleccionada != null) {
            this.accionSeleccionada = accionSeleccionada;
        }
    }

    public List<SelectItem> getTiposSolicitudItems() {
        return tiposSolicitudItems;
    }

    public void setTiposSolicitudItems(List<SelectItem> tiposSolicitudItems) {
        this.tiposSolicitudItems = tiposSolicitudItems;
    }

    public String getMensaje() {
        return mensaje;
    }

    public void setMensaje(String mensaje) {
        this.mensaje = mensaje;
    }

    public String getTipoUsuarioElementosSeleccionado() {
        return tipoUsuarioElementosSeleccionado;
    }

    public void setTipoUsuarioElementosSeleccionado(String tipoUsuarioElementosSeleccionado) {
        this.tipoUsuarioElementosSeleccionado = tipoUsuarioElementosSeleccionado;
    }

    public String getTipoUsuarioRequerimientosSeleccionado() {
        return tipoUsuarioRequerimientosSeleccionado;
    }

    public void setTipoUsuarioRequerimientosSeleccionado(String tipoUsuarioRequerimientosSeleccionado) {
        this.tipoUsuarioRequerimientosSeleccionado = tipoUsuarioRequerimientosSeleccionado;
    }

    public String getIpOrigenFirewall() {
        return ipOrigenFirewall;
    }

    public void setIpOrigenFirewall(String ipOrigenFirewall) {
        this.ipOrigenFirewall = ipOrigenFirewall;
    }

    public String getIpDestinoFirewall() {
        return ipDestinoFirewall;
    }

    public void setIpDestinoFirewall(String ipDestinoFirewall) {
        this.ipDestinoFirewall = ipDestinoFirewall;
    }

    public List<SelectItem> getAccionesItems() {
        return accionesItems;
    }

    public void setAccionesItems(List<SelectItem> accionesItems) {
        this.accionesItems = accionesItems;
    }

}
